/**
 * 文件名：AbstractTask.java
 *
 * 版本信息：v1.0
 * 日期：2011-10-20
 */
package org.waddy.framework.app.task;

import java.util.TimerTask;

import org.apache.log4j.Logger;

/**
 * Name:AbstractTask<br>
 * Description:安全的服务线程<br>
 *
 * @author 张大朋 2011-10-20 下午04:44:17
 * @version 1.0
 */
public abstract class AbstractTimerTask extends TimerTask {
	public static Logger log = Logger.getLogger(AbstractTimerTask.class);
	
	//线程尝试重启次数
	private final int MAX_ATTEMPT_TIMES =5;
	//线程尝试重启间隔时间，单位：分钟
	private final int ATTEMPT_INTERVAL=1;
	//间隔时间，单位：秒钟
	protected Long WORK_INTERVAL =30L; //工作线程私有的工作周期间隔时间
	//继续运行标志
	private boolean runFlag = false;
	
	public boolean isRunFlag() {
		return runFlag;
	}

	public void setRunFlag(boolean runFlag) {
		this.runFlag = runFlag;
	}

	//服务线程首次初始化
	public abstract void init() throws Exception;
	
	//服务线程的执行体
	public abstract void exec() throws Exception;
	
	@Override
	public void run() {
		/**
		 * 线程异常中断重启机制
		 * 程序在初始化或运行中出现异常中断时，自动尝试重启
		 * 尝试次数：MAX_ATTEMPT_TIMES
		 * 尝试间隔时间：ATTEMPT_INTERVAL 分钟，第1次休眠ATTEMPT_INTERVAL分钟，第2次休眠ATTEMPT_INTERVAL*2分钟，...
		 */
		int attemtTimes =0;
		log.info("runFlag="+runFlag);
		while(runFlag){
			try {
				log.info("工作线程初始化...");
				init();
				while( true){
					log.info("工作周期开始...");
					exec();
					log.info("工作周期结束，开始休眠<"+WORK_INTERVAL+"秒钟>...");
					try {
						Thread.sleep(WORK_INTERVAL*1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					//若成功执行一个工作周期，则把失败尝试次数重置为0
					attemtTimes = 0;
				}
			} catch (Exception e1) {
				attemtTimes++;
				log.error("工作线程运行中连续第"+attemtTimes+"次出现故障：",e1);
				if(attemtTimes>MAX_ATTEMPT_TIMES){
					log.fatal("连续执行失败次数超过上限（"+MAX_ATTEMPT_TIMES+"次），系统停止运行！！！");
					runFlag=false;
				}else{
					log.info("故障休眠"+ATTEMPT_INTERVAL*attemtTimes+"分钟后重新启动工作线程...");
					try {
						Thread.sleep(ATTEMPT_INTERVAL*attemtTimes*1000*60);
					} catch (InterruptedException e) {
					}
					log.info("故障休眠结束，开始第"+attemtTimes+"次重启...");
				}
			}
		}
	}
}
